package com.ecnu.sei.app.course;

import java.util.Set;

import com.ecnu.sei.app.Scheduler;
import com.ecnu.sei.app.resources.Time;
import com.ecnu.sei.app.teacher.AbstractTeacher;
import com.ecnu.sei.app.teacher.Official;

/*
 *  universal rules for all kinds of courses:
 * 
 *  1. CompulsoryCourse => 3 proctors (one prime, two vice)
 *     ElectiveCourse   => 2 proctors (one prime, one vice)
 *  2. normally, a course's lecturer will be the prime proctor, choose another one
 *     only if a teacher is not available for being lecturers for more than one course
 *  3. one backup proctor, from those who has proctored below-average number of courses in one semester  
 */

public abstract class AbstractCourse {

  public static final int BACKUP_NUM = 2;

  protected CourseInfo info = new CourseInfo();

  protected Scheduler scheduler = Scheduler.getScheduler();

  public AbstractCourse() {}

  public AbstractCourse(CourseInfo info) {
    this.info = info;
  }

  public CourseInfo getCourseInfo() {
    return info;
  }

  public void SetCourseInfo(CourseInfo info) {
    this.info = info;
  }

  public Time getExamTime() {
    return info.getExamInfo().getTime();
  }

  public boolean hasEnoughProctors() {
    ExamInfo examInfo = info.getExamInfo();

    Set<AbstractTeacher> proctors = examInfo.getProctor();
    if (null == proctors || proctors.size() < this.getProctorNum()) {
      return false;
    } else {
      return true;
    }
  }

  public boolean addProctor(AbstractTeacher teacher) {
    ExamInfo examInfo = info.getExamInfo();
    Set<AbstractTeacher> proctors = examInfo.getProctor();

    if (!proctors.contains(teacher)) {
      if (teacher.isAvailableFor(this)) {
        proctors.add(teacher);
        return true;
      }
    }

    return false;
  }



  public boolean addBackup(AbstractTeacher backup) {
    if (backup.isAvailableFor(this)) {
      ExamInfo examInfo = info.getExamInfo();
      examInfo.addBackup(backup);
      backup.addProctor(this);

      if (BACKUP_NUM == examInfo.getBackup().size()) {
        return true;
      }
    }

    return false;

  }

  public boolean setPatrol(Official patrol) {
    if (patrol.isAvailableForPatrol(this)) {
      ExamInfo examInfo = info.getExamInfo();
      examInfo.setPatrol(patrol);
      return true;
    } else {
      return false;
    }

  }

  abstract public int getProctorNum();
  abstract public boolean setResource();
  abstract public boolean setResourcePending();
}
